/**
* modified from https://github.com/dcloudio/hello-uniapp/blob/master/components/mpvue-echarts/src/echarts.vue
*/
<template>
	<canvas v-if="canvasId" class="ec-canvas" :id="canvasId" :canvasId="canvasId" @touchstart="touchStart" @touchmove="touchMove"
	 @touchend="touchEnd" @error="error" @longtap="longTap"></canvas>
</template>

<script>
	import WxCanvas from './wx-canvas';
	import throttle from 'lodash/throttle';

	function wrapTouch(event) {
		for (let i = 0; i < event.touches.length; ++i) {
			const touch = event.touches[i]
			touch.offsetX = touch.x
			touch.offsetY = touch.y
		}
		return event
	}

	export default {
		props: {
			canvasId: {
				type: String,
				default: 'ec-canvas'
			},
			lazyLoad: {
				type: Boolean,
				default: false
			},
			disableTouch: {
				type: Boolean,
				default: false
			},
			throttleTouch: {
				type: Boolean,
				default: false
			}
		},
		data() {
			return {
				istouch: false,
				startPoints: [],
				movePointers: [],
				isMove: false
			}
		},
		// #ifdef H5
		mounted() {
			if (!this.lazyLoad) this.init();
		},
		// #endif
		// #ifndef H5
		onReady() {
			if (!this.lazyLoad) this.init();
		},
		// #endif
		beforeUpdate(e) {
			// console.log('beforeUpdate', e)
		},
		methods: {
			setChart(chart) {
				this.chart = chart
			},
			longTap(e) {
				const {
					chart
				} = this;
				const touch = e.mp.touches[0];
				if (e.mp.touches.length >= 2) { // 两指以上触摸
					this.changeChartAxisPointerShow(false);
				} else {
					// 如果在定时触发时间内移动了
					if (this.isMove) return;
					this.changeChartAxisPointerShow(true);
					// 再主动触发一次mousemove事件，使坐标指示器能够直接马上显示出来
					chart.getZr().handler.dispatch('mousemove', {
						zrX: touch.x,
						zrY: touch.y
					});
				}
				console.log(e);
				console.log('length', e.touches.length);
			},
			init() {
				const {
					canvasId
				} = this;
				this.ctx = uni.createCanvasContext(canvasId, this);
				this.canvas = new WxCanvas(this.ctx, canvasId);
				const query = uni.createSelectorQuery().in(this);
				query
					.select(`#${canvasId}`)
					.boundingClientRect(res => {
						if (!res) {
							setTimeout(() => this.init(), 50);
							return;
						}
						this.$emit('onInit', {
							width: res.width,
							height: res.height
						});
					})
					.exec();
			},

			canvasToTempFilePath(opt) {
				const {
					canvasId
				} = this;
				this.ctx.draw(true, () => {
					uni.canvasToTempFilePath({
						canvasId,
						...opt
					});
				});
			},
			// 计算坐标轴上两点之间的距离
			getDistance(p1, p2) {
				const x = p2.x - p1.x,
					y = p2.y - p1.y;
				return Math.sqrt((x * x) + (y * y));
			},

			// 触发图表的dataZoom改变
			changeChartDataZoom(newDataZoomStart, initDataZoomEnd) {
				this.chart.dispatchAction({
					type: 'dataZoom',
					// 可选，dataZoom 组件的 index，多个 dataZoom 组件时有用，默认为 0
					dataZoomIndex: 0,
					// 开始位置的百分比，0 - 100
					start: newDataZoomStart,
					// 结束位置的百分比，0 - 100
					end: initDataZoomEnd,
					// 开始位置的数值
					// startValue: number,
					// 结束位置的数值
					// endValue: number
				});
			},
			// 改变坐标轴指示器的显示与否
			changeChartAxisPointerShow(isShow) {
				const {
					chart
				} = this;
				chart.setOption({
					axisPointer: {
						show: isShow,
					},
				});
				this.isShowAxisPointer = isShow;
			},

			touchStart(e) {
				const {
					disableTouch,
					chart
				} = this;
				if (disableTouch || !chart || !e.mp.touches.length) return;
				const touch = e.mp.touches[0];
				const handler = chart.getZr().handler;
				handler.dispatch('mousedown', {
					zrX: touch.x,
					zrY: touch.y
				});
				// handler.dispatch('mousemove', {
				// 	zrX: touch.x,
				// 	zrY: touch.y
				// });
				handler.processGesture(wrapTouch(e), 'start')


				// 获取起点坐标
				this.startPoints = e.mp.touches;
				// 获取初始的dataZoom位置
				this.initDataZoomStart = chart.getModel().option.dataZoom[0].start; // 开始位置的百分比
				this.initDataZoomEnd = chart.getModel().option.dataZoom[0].end; // 结束位置的百分比
				// console.log('this.chart', chart);
				// console.log('touchStart===e', e)
			},

			/* touchMove事件修改加上节流 */
			touchMove: throttle(function(e) {
				// var old = new Date().getTime();
				const {
					disableTouch,
					throttleTouch,
					chart,
					lastMoveTime,
					initDataZoomStart,
					initDataZoomEnd
				} = this;
				if (disableTouch || !chart || !e.mp.touches.length) return;
				if (throttleTouch) {
					const currMoveTime = Date.now();
					if (currMoveTime - lastMoveTime < 240) return;
					this.lastMoveTime = currMoveTime;
				}
				const touch = e.mp.touches[0];
				const handler = chart.getZr().handler;

				handler.dispatch('mousemove', {
					zrX: touch.x,
					zrY: touch.y
				});
				handler.processGesture(wrapTouch(e), 'change')

				// chart.dispatchAction({
				// 	type: 'updateAxisPointer',
				// 	currTrigger: 'mousemove',
				// 	x: touch.x,
				// 	y: touch.y
				// })

				const touchLength = e.mp.touches.length; // 手指数

				// 标记手指有移动
				this.isMove = true;

				if (initDataZoomStart !== undefined && initDataZoomEnd !== undefined) {
					let dataZoomDiff = initDataZoomEnd - initDataZoomStart;
					if (touchLength === 1 && !this.isShowAxisPointer) { // 单指移动并且不显示坐标指示器
						const chartWidth = chart.getWidth(); // 获取图表的宽度
						const singleMoveDis = this.startPoints[0].x - e.mp.touches[0].x; // 计算单指移动的距离
						const changeDataZoom = dataZoomDiff * (singleMoveDis / chartWidth); // 计算dataZoom需要移动的长度
						const singleDataZoomMoveDis = Number((changeDataZoom / 2).toFixed(2)) * 2; // 计算dataZoom的start和end的需要移动的值
						this.changeChartDataZoom(initDataZoomStart + singleDataZoomMoveDis, initDataZoomEnd + singleDataZoomMoveDis);
					} else if (touchLength === 2) { //  双指移动
						let scale = 0; // 缩放比例
						// 双指移动
						const startDistance = this.getDistance(this.startPoints[0], this.startPoints[1]); // 最初两指间的距离
						const moveDistance = this.getDistance(e.mp.touches[0], e.mp.touches[1]); // 移动过程中两指间的距离
						scale = startDistance / moveDistance; // 计算缩放比例
						scale = Number(scale.toFixed(2));
						let newDataZoomDiff = dataZoomDiff * scale;
						let dataZoomDiffDiff = dataZoomDiff - newDataZoomDiff; // 计算初始和移动过程中dataZoom的差值
						let newDataZoomStart = initDataZoomStart + dataZoomDiffDiff;
						let newDataZoomEnd = initDataZoomEnd;
						if (newDataZoomStart <= 0) {
							newDataZoomEnd = newDataZoomEnd - newDataZoomStart;
							newDataZoomStart = 0; // dataZoom的start置零
						}
						console.log('newDataZoomStart', newDataZoomStart)
						console.log('newDataZoomEnd', newDataZoomEnd)
						// 触发图表的缩放
						this.changeChartDataZoom(newDataZoomStart, newDataZoomEnd)
					}
				}

				// var newTime = new Date().getTime();
				// console.log('distanceTime', newTime - old);

			}, 100 , {
				leading: true,
				trailing: false
			}),

			touchEnd(e) {
				const {
					disableTouch,
					chart
				} = this;
				if (disableTouch || !chart) return;
				const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {};
				const handler = chart.getZr().handler;
				handler.dispatch('mouseup', {
					zrX: touch.x,
					zrY: touch.y
				});
				handler.dispatch('click', {
					zrX: touch.x,
					zrY: touch.y
				});
				handler.processGesture(wrapTouch(e), 'end')
				/* 部分值得重新初始化 */
				// 手指移开清除初始的initDataZoom值
				this.initDataZoomStart = undefined;
				this.initDataZoomEnd = undefined;
				this.isMove = false;
				// 清楚显示坐标显示器的定时器
				this.axisPointerTimeout && clearTimeout(this.axisPointerTimeout);
				// 手指离开一分钟后隐藏掉坐标指示器
				setTimeout(() => {
					chart.dispatchAction({
						type: 'updateAxisPointer',
						currTrigger: 'leave'
					});
					this.changeChartAxisPointerShow(false);
				}, 350); // 延时隐藏时间和longTap延时时间一样

				// console.log('touchEnd', e)
			}
		}
	};
</script>

<style scoped>
	.ec-canvas {
		width: 100%;
		height: 100%;
		flex: 1;
	}
</style>
